#!/usr/bin/env python
# -*- coding:utf8 -*-
# uncompyle6 version 2.15.1
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.10 (default, Jul  1 2017, 13:36:56) 
# [GCC 4.4.6 20110731 (Red Hat 4.4.6-4)]
# Embedded file name: ./esb/common/errors.py
# Compiled at: 2017-11-16 15:44:28
"""
Tencent is pleased to support the open source community by making 蓝鲸智云(BlueKing) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
"""
import copy
ERROR_CODE_PREFIX_SYSTEM = '0'
ERROR_CODE_PREFIX_THIRD_PARTY = '1'

def wrap_error_code(code):
    """
    包装第三方系统返回的错误代码
    """
    return ERROR_CODE_PREFIX_THIRD_PARTY + str(code)


class BaseException(Exception):
    pass


class RequestThirdPartyException(BaseException):
    """
    当请求第三方系统时抛出的异常
    """

    def __init__(self, raw_exc, system_name, interface_name):
        self.raw_exc = raw_exc
        self.system_name = system_name
        self.interface_name = interface_name

    def __str__(self):
        return u'组件请求第三方系统%s接口%s出错：%s，请稍后重试或联系组件开发者处理' % (
         self.system_name, self.interface_name, self.raw_exc.message)

    def get_message(self):
        """
        返回到终端用户的错误信息
        """
        return u'组件请求第三方系统%s接口%s出错：%s，请稍后重试或联系组件开发者处理' % (
         self.system_name, self.interface_name, self.raw_exc.message)


class RequestSSLException(BaseException):
    """SSL错误，明确错误信息
    """

    def __init__(self, raw_exc, system_name, interface_name):
        self.raw_exc = raw_exc
        self.system_name = system_name
        self.interface_name = interface_name

    def __str__(self):
        return self.get_message()

    def get_message(self):
        """
        返回到终端用户的错误信息
        """
        if isinstance(self.raw_exc.cert, tuple):
            self.raw_exc.cert = (u'，').join(self.raw_exc.cert)
        return u'组件请求第三方系统%s接口%s SSL出错：SSL配置文件【%s】不存在或者不合法，请按文档获取证书并解压放入【%s】' % (
         self.system_name, self.interface_name, self.raw_exc.cert, self.raw_exc.SSL_ROOT_DIR)


class TestHostNotFoundException(BaseException):
    """
    当以测试环境访问没有host_test的SmartHost时抛出
    """
    pass


class RequestBlockedException(BaseException):
    """
    当前请求被屏蔽之后抛出的异常
    """
    pass


class APIError(BaseException):
    """
    API Error
    """

    def __init__(self, code):
        self.code = code
        BaseException.__init__(self, code.prompt)

    def __str__(self):
        return '<APIError %s[%s]: %s>' % (
         self.code.status, self.code.code, self.code.prompt)

    def format_prompt(self, prompt=None, replace=False, args=(), kwargs={}):
        """
        Using a customized prompt for this ErrorCode
        """
        self.code = copy.copy(self.code)
        if prompt:
            if replace:
                self.code.prompt = prompt
            else:
                self.code.prompt += ', %s' % prompt
        if args:
            self.code.prompt = self.code.prompt % args
        if kwargs:
            self.code.prompt = self.code.prompt % kwargs
        return self


class ErrorCode(object):
    """
    Error Code class
    """

    def __init__(self, code_name, code, prompt, status=200):
        self.code_name = code_name
        self.code = code
        self.prompt = prompt
        self.status = status

    def as_dict(self):
        return {'result': False,
           'code': self.code,
           'data': None,
           'message': self.prompt
           }


class ErrorCodes(object):
    """
    错误代码规范
    
      * 50000: 默认错误代码
    """
    error_codes = (
     ErrorCode('OPERATOR_REQUIRED', '10001', u'必须指定当前操作者'),
     ErrorCode('ARGUMENT_ERROR', '10002', u'参数错误'),
     ErrorCode('RATE_LIMIT_RESTRICTION', '10004', u'访问频率限制'),
     ErrorCode('INACTIVE_CHANNEL', '20003', u'Not found, inactive channel'),
     ErrorCode('COMPONENT_NOT_FOUND', '20004', u'Not found, component class not found'),
     ErrorCode('BUFFET_CANNOT_FORMAT_PATH', '20050', u'该组件的目标请求地址路径不能被格式化'),
     ErrorCode('USER_PERMISSION_DENIED', '40000', u'用户权限不足'),
     ErrorCode('APP_PERMISSION_DENIED', '40100', u'APP权限不足'),
     ErrorCode('COMMON_ERROR', '50000', u'系统错误'),
     ErrorCode('EXTERNAL_ERROR', '50001', u'请求外部接口错误'),
     ErrorCode('TEST_HOST_NOT_FOUND', '50002', u'错误，该组件不支持在测试环境下访问，没有配置任何测试系统地址'),
     ErrorCode('REQUEST_BLOCKED', '50003', u'到第三方请求被屏蔽'))
    _error_codes_dict = {}
    for error_code in error_codes:
        _error_codes_dict[error_code.code_name] = error_code

    def __getattr__(self, code_name):
        error_code = self._error_codes_dict[code_name]
        return APIError(error_code)


class RequestThirdPartyErrorCodes(object):
    """
    请求第三方系统错误代码
    """
    error_codes = {'STATUS_CODE_500': u'第三方系统内部错误',
       'STATUS_CODE_502': u'第三方系统Bad Gateway',
       'STATUS_CODE_403': u'第三方系统禁止访问此接口',
       'STATUS_CODE_404': u'第三方系统不存在此接口',
       'STATUS_CODE_302': u'第三方系统重定向此接口'
       }


error_codes = ErrorCodes()
request_third_party_error_codes = RequestThirdPartyErrorCodes()

class CommonAPIError(APIError):
    """
    Shortcut for returning an error response
    """

    def __init__(self, message, error_code=None, status=None):
        """
        初始化一个常用的通用错误
        
        :param str message: 自定义的错误消息
        :param str error_code: 返回到相应的错误代码，默认50000
        """
        self.message = message
        code = error_codes.COMMON_ERROR.format_prompt(message, replace=True).code
        if error_code:
            code.code = error_code
        if status:
            code.status = status
        super(CommonAPIError, self).__init__(code)
